﻿using CommunityToolkit.Mvvm.ComponentModel;
using HardToolApp.Tool;
using HardToolApp.ViewModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HardToolApp.Model
{
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommCmd
    {
        [Description("串口")]
        COMM_UART = 1,
        [Description("ADC(无用)")]
        COMM_ADC,
        [Description("IIC主机")]
        COMM_IIC_MASTER,
        [Description("IIC从机")]
        COMM_IIC_SLAVE,
        [Description("SPI主机")]
        COMM_SPI_MASTER,
        [Description("SPI从机")]
        COMM_SPI_SLAVE,
        [Description("GPIO")]
        COMM_GPIO,
        [Description("PWM")]
        COMM_PWM,
        [Description("在线升级(无用)")]
        COMM_UPDATE,
    };

    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommStatus
    {
        [Description("成功")]
        COM_OK   = 0,
        [Description("失败")]
        COM_FAIL,
        [Description("超时")]
        COM_TIMEOUT ,
        [Description("内存分配失败")]
        COM_MEM,
        [Description("模式错误")]
        COM_MODE,
        [Description("意外中止")]
        COM_STOP,
    };

    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommSubCmdUart
    {
        [Description("串口设置")]
        COMM_SUB_UART_SET_PARAM = 1,
        [Description("串口发送")]
        COMM_SUB_UART_SEND,
        [Description("串口接收")]
        COMM_SUB_UART_REC
    };

    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommSubCmdADC
    {
        [Description("ADC数据(无用)")]
        COMM_SUB_ADC_UPDATE = 1,
    };
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommSubCmdIICMaster
    {
        [Description("参数设置")]
        COMM_SUB_IIC_MASTER_SET_PARAM = 1,
        [Description("写入")]
        COMM_SUB_IIC_MASTER_WRITE,
        [Description("读取")]
        COMM_SUB_IIC_MASTER_READ
    };
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommSubCmdIICSlave
    {
        [Description("参数设置")]
        COMM_SUB_IIC_SLAVE_SET_PARAM = 1,
        [Description("写入")]
        COMM_SUB_IIC_SLAVE_WRITE,
        [Description("读取")]
        COMM_SUB_IIC_SLAVE_READ
    };
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommSubCmdSPIMaster
    {
        [Description("参数设置")]
        COMM_SUB_SPI_MASTER_SET_PARAM = 1,
        [Description("写入")]
        COMM_SUB_SPI_MASTER_WRITE,
        [Description("读取")]
        COMM_SUB_SPI_MASTER_READ,
        [Description("写入后读取")]
        COMM_SUB_SPI_MASTER_WRITE_READ,
    };
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommSubCmdSPISlave
    {
        [Description("参数设置")]
        COMM_SUB_SPI_SLAVE_SET_PARAM = 1,
        [Description("写入")]
        COMM_SUB_SPI_SLAVE_WRITE,
        [Description("读取")]
        COMM_SUB_SPI_SLAVE_READ,
    };
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommSubGPIO
    {
        [Description("端口设置")]
        COMM_SUB_GPIO_PIN_SET = 1,
        [Description("高低电平转换")]
        COMM_SUB_GPIO_HL_CHANGE,
        [Description("电平设置")]
        COMM_SUB_GPIO_LEVEL_SET,
        [Description("电平读取")]
        COMM_SUB_GPIO_LEVEL_READ,
    };
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    public enum CommSubPWM
    {
        [Description("参数设置")]
        COMM_SUB_PWM_SET_PARAM = 1,
        [Description("开关PWM")]
        COMM_SUB_PWM_OPEN_CLOSE,
    };

    public enum CommSubUpdate
    {
        COMM_SUB_UPDATE_BEGIN = 1,
        COMM_SUB_UPDATE_DATA_SEND,
        COMM_SUB_UPDATE_STOP,
        COMM_SUB_UPDATE_VERSION
    };
    public abstract class Peripheral:ObservableObject
    {
        CommCmd _commType;
        public CommCmd commType { get { return _commType; } }
        byte _subCmd;
        public byte subCmd { get { return _subCmd; } set { SetProperty(ref _subCmd, value); } }
        public string _cmdName;
        public string cmdName { get => _cmdName; set { SetProperty(ref _cmdName, value); } }
        public Peripheral(CommCmd type)
        {
            _commType = type;
            subCmd = 1;
            cmdName = EnumExtensions.GetDescription(_commType);
        }
    }
    public abstract class Communicate : Peripheral
    {
       // public static string[] ErrorString = { "成功","失败","超时","内存分配失败","模式错误","意外中止"};
        public static string[] SubString = { "", "参数设置", "写入", "读取", "写入后读取" };
        public enum SubCmd
        { 
            SetParam = 1,
            SendData,
            ReadData,
            SendReadData
        };

        
        string _sendBytes;
        public string sendBytes { get { return _sendBytes; } set { SetProperty(ref _sendBytes, value); } }
        string _receiveBytes;
        public string receiveBytes { get { return _receiveBytes; } set { SetProperty(ref _receiveBytes, value); } }
        public Communicate(CommCmd type):base(type)
        {
        }
    }

    public class ReplyClass
    {
        public byte cmd { get; set; }
        public byte subCmd { get; set; }
        public byte data { get; set; }
        public ReplyClass(byte cmd, byte subCmd, byte data)
        {
            this.cmd = cmd;
            this.subCmd = subCmd;
            this.data = data;
        }
    }


    public class UartSendClass
    {
        public byte[] data { get; set; }
        public UartSendClass(byte[] data) {  this.data = data; }
    }

    public class IICMasterWriteClass
    {
        public byte[] data { get; set; }
        public UInt16 timeout { get; set; }
        public IICMasterWriteClass(byte[] data,UInt16 timeout) { this.data = data; this.timeout = timeout; }
    }

    public class IICMasterReadClass
    {
        public byte len { get; set; }
        public byte addr { get; set; }
        public UInt16 timeout { get; set; }
        public IICMasterReadClass(byte addr, byte len, UInt16 timeout) { this.addr = addr; this.len = len;this.timeout = timeout; }
    }

    public class IICSlaveWriteClass
    {
        public byte[] data { get; set; }
        public IICSlaveWriteClass(byte[] data) { this.data = data; }
    }

    public class IICSlaveReadClass
    {
        public byte len { get; set; }
        public IICSlaveReadClass( byte len) { this.len = len;  }
    }

    public class SPIMasterWriteClass
    {
        public byte[] data { get; set; }
        public SPIMasterWriteClass(byte[] data) { this.data = data; }
    }

    public class SPIMasterReadClass
    {
        public byte len { get; set; }
        public SPIMasterReadClass(byte len) { this.len = len; }
    }

    public class SPIMasterWriteReadClass
    {
        public byte len { get; set; }
        public byte[] data { get; set; }
        public UInt32 delay { get; set; }
        public SPIMasterWriteReadClass(byte[] data, byte len, UInt32 delay) { this.data = data; this.len = len; this.delay = delay; }
    }


    public class SPISlaveWriteClass
    {
        public byte[] data { get; set; }
        public SPISlaveWriteClass(byte[] data) { this.data = data; }
    }

    public class SPISlaveReadClass
    {
        public byte len { get; set; }
        public SPISlaveReadClass(byte len) { this.len = len; }
    }
}
